﻿using Common;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using EC3_6CLH.Model;
using EC3_6CLH.View;
using LiveCharts;
using NewDevice.TCPIP;
using System.Collections.ObjectModel;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;

namespace EC3_6CLH.ViewModel
{
    public partial class MainViewModel : ObservableObject
    {
        private int _logIndex = 0;
        private readonly Lock _logLock = new Lock();
        private bool _isRunning;

        public event EventHandler? CloseRequested;

        [ObservableProperty] private string _licenseMessage;
        [ObservableProperty] private string _licenseSn;
        [ObservableProperty] private string _log = string.Empty;
        [ObservableProperty] private string _systemTime = string.Empty;
        [ObservableProperty] private int _passCount;
        [ObservableProperty] private int _ngCount;
        [ObservableProperty] private UserControl _currentView;
        public Func<ChartPoint, string> PointLabel { get; set; }
        //public TestConfig TestConfig { get; set; }

        private readonly Dictionary<string, Func<object>> _viewFactories = new()
        {
            ["运行监控"] = () => new HomeView(),
            ["设备调试"] = () => new DebugView(),
            ["用户管理"] = () => new UserManageView()
        };

        [RelayCommand]
        public void WindowClosed(object obj)
        {
            MessageBoxResult result = MessageBoxResult.None;
            Application.Current.Dispatcher.Invoke(() =>
            {
                result = MessageBox.Show("是否退出测试系统?", "警告", MessageBoxButton.YesNo);
            });
            if (result == MessageBoxResult.Yes)
            {
                _isRunning = false;
#if PROJFINISHED
                IoModule.SetAllOutputs(false);
#endif
                // 释放资源
                CloseRequested?.Invoke(this, EventArgs.Empty);
            }
        }

        [RelayCommand]
        public async Task WindowLoadAsync()
        {
            _isRunning = true;
            _ = UpdateSystemTime();

            PassCount = 0;
            NgCount = 0;
            try
            {
                GlobalValue.DiDoDefine.ParseFile("config.xlsx", "IODefine");
                GlobalValue.Config.ParseFile("config.xlsx", "参数配置");
                GlobalValue.TestConfig = new TestConfig();
                GlobalValue.TestConfig.LoadInitParams(GlobalValue.Config.GetParams("当前机种配置文件路径"));

                // Workstations Initialize
                for (int i = 0; i < 12; i++)
                {
                    int id = i + 1;
                    string ip = GlobalValue.TestConfig.Config.GetParams($"工位{i+1}IP");
                    int port = 502;
                    TimeSpan time = TimeSpan.FromMinutes(int.Parse(GlobalValue.TestConfig.Config.GetParams($"老化时间")));

                    WorkstationModel model = new WorkstationModel(id, ip, port, time)
                    {
                        WorkstationState = WorkstationState.Idle,
                        IsLock = i >= 10,
                        Sn = "",
                        WorkstationStateChangedEvent = OneStationWorkstationStateChanged,
                        LogMessageEvent = OneStationLogMessage
                    };

                    Workstations.Add(model);
                }

                foreach (var item in GlobalValue.DiDoDefine.ParamList)
                {
                    string key = item.Key;
                    int value = int.Parse(item.Value);
                    bool isDo = key.Contains("DO");
                    DiDoStatuses.Add(new DiDoStatus { ChannelIndex = value, Description = key, IsDo = isDo, Status = true, StatusChanged = IoStatusChanged });
                }

                InitDebug();

                _ = InitDevice();
                await Task.Delay(10);
            }
            catch (Exception ex)
            {
                AppendLog(ex.Message + "!");
            }
        }

        private async Task InitDevice()
        {
            try
            {
                await IoModule.ConnectAsync();
                IoModule.StartBackgroundRefresh();
#if PROJFINISHED
                IoModule.SetAllOutputs(false);
#endif

                _ = UpdateDiDo();

                AppendLog("设备初始化完成");
                //await Task.Delay(10);
            }
            catch (Exception e)
            {
                MyLog.Error(e);
                AppendLog(e.Message + "!");
            }
        }

        private void OneStationLogMessage(string obj)
        {
            AppendLog(obj);
        }

        private void OneStationWorkstationStateChanged(WorkstationState obj)
        {
            if (obj == WorkstationState.Ok)
            {
                PassCount++;
            }
            else if (obj == WorkstationState.Ng)
            {
                NgCount++;
            }
        }

        [RelayCommand]
        private void Navigate(string viewName)
        {
            switch (viewName)
            {
                case "运行监控":
                    CurrentView = new HomeView();
                    break;

                case "设备调试":
                    CurrentView = new DebugView();
                    break;

                case "用户管理":
                    CurrentView = new UserManageView();
                    break;
            }
        }

        [RelayCommand]
        public void StartTest(object obj)
        {
            foreach (var item in Workstations)
            {
                Task.Run(() =>
                {
                    _= item.StartTestAsync();
                });
            }
        }

        [RelayCommand]
        public async Task Reset()
        {
            try
            {
                await Task.Delay(0);
                foreach (var item in Workstations)
                {
                    item.Reset();
                }
            }
            catch (Exception ex)
            {
                MyLog.Error(ex);
                AppendLog(ex.Message + "!");
            }
        }

        [RelayCommand]
        public async Task Stop()
        {
            await Task.Delay(0);
            foreach (var item in Workstations)
            {
                _ = item.StopAsync();
            }
        }

        [RelayCommand]
        public void ClearOkNgCount(object obj)
        {
            PassCount = 0;
            NgCount = 0;
        }

        private void AppendLog(string msg)
        {
            Application.Current.Dispatcher.Invoke(() =>
            {
                lock (_logLock)
                {
                    Log = $"[{_logIndex++}]{msg}";
                    MyLog.Info(msg);
                }
            });
        }

        private async Task UpdateSystemTime()
        {
            while (_isRunning)
            {
                SystemTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                await Task.Delay(1000);
            }
        }

        public ObservableCollection<WorkstationModel> Workstations { get; } = new ObservableCollection<WorkstationModel>();
        public GlobalAlarmService GlobalAlarm { get; } = new();

        private void EmergencyStop()
        {
            GlobalAlarm.TriggerAlarm();
        }

        public MainViewModel()
        {
            IoModule = new PqwIoTcp(inputChannels: 12, outputChannels: 24);
            LicenseSn = GlobalValue.LicenseSn;
            LicenseMessage = GlobalValue.LicenseMessage;

            PointLabel = chartPoint =>
                $"{chartPoint.Y} ({chartPoint.Participation:P})";
            CurrentView = new HomeView();

            //Navigate("运行监控");
        }
    }
}